package com.jnc.pay.core.vertx;

import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.MessageCodec;

import java.io.*;

/**
 * @Author: jjn
 * @Date: 2019/2/1 19:04
 * @Desc: 消息编解码器
 */
public class ObjectCodec implements MessageCodec<Object, Object> {

    /**
     * 将消息实体封装到Buffer用于传输
     * 实现方式：使用对象流从对象中获取byte数组，然后追加到Buffer
     * @param buffer
     * @param o
     */
    @Override
    public void encodeToWire(Buffer buffer, Object o) {
        final ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(bout);
            oos.writeObject(o);
            buffer.appendBytes(bout.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bout != null){
                try {
                    bout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    /**
     * 从buffer中获取传输的消息实体
     * @param i
     * @param buffer
     * @return
     */
    @Override
    public Object decodeFromWire(int i, Buffer buffer) {
        final ByteArrayInputStream bis = new ByteArrayInputStream(buffer.getBytes());
        ObjectInputStream ois = null;
        Object msg = null;
        try {
            ois = new ObjectInputStream(bis);
            msg = ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return msg;
    }

    /**
     * 如果是本地消息则直接返回
     * @param o
     * @return
     */
    @Override
    public Object transform(Object o) {
        return o;
    }

    /**
     * 编解码器的名称：
     *              必须唯一，用于发送消息时识别编解码器，以及取消编解码器
     * @return
     */
    @Override
    public String name() {
        return "ObjectCodec";
    }

    /**
     * 用于识别是否是用户编码器
     * 自定义编解码器通常使用-1
     * @return
     */
    @Override
    public byte systemCodecID() {
        return -1;
    }
}
